<template>
	<view class="">
		<map :latitude="mapCenterLatitude" :longitude="mapCenterLongitude" scale="13" :markers="markers"
			:polyline="polyline">
		</map>
	</view>
</template>

<script>
	// import markersList from './lib/markers.js'
	// 引入高德地图
	import amapFile from './lib/amap-wx.130.js'
	// 配置高德地图key
	let myAmapFun = new amapFile.AMapWX({
		key: '9deb4a614df0f484b81b802b4beafe7b'
	});
	import baseUrl from '@/api/url.js';
	import Encr from '@/common/aes.js';
	import Voice from './lib/QS-baiduyy.js'
	// const requestUrl = "http://106.13.116.185:8088"; //生产地址
	const requestUrl = "http://ccwx.jltobacco.com.cn:4000/yancaoMap/"; //生产地址

	export default {
		name: "mapSmoke",
		data() {
			return {
				AmapJS: null, // JSapi实例
				lngLatInterval: null, // 回传坐标定时器
				locationSetInterVal: null, // 车辆位置定时器
				carID: "", // 当前运行车辆ID
				markers: [], // 线路站点列表
				siteNum: -1, // 正在执行站（第1站/第...站）
				// 地图线
				polylineColor: "#0088ff", // 选中路线执行方案颜色
				polyline: [],
				polylineComputed: [],
				mapCenterLatitude: 43.798917,
				mapCenterLongitude: 125.309814
			}
		},
		onLoad() {
			this.initLinePlan()
			// 确认到站
			uni.$on('saveSiteNum', (data) => {
				if (data.siteNum) {
					this.saveSiteNum(data.siteNum)
				}
			})
			// 自定义选择站点
			uni.$on('selectSiteNum', (data) => {
				if (data.siteNum || data.siteNum == 0) {
					if (data.driverMark) {
						this.selectSiteNum(data.siteNum, data.driverMark)
					} else {
						return uni.showToast({
							title: "定位坐标失败，请重新选站！",
							icon: "none"
						})
					}
				}
			})
			// 接收选择方案类型
			uni.$on('selectPlan-MapPopup', (data) => {
				if (data.polyline) {
					this.polyline = []
					this.polyline.push(data.polyline)
				}
			})

		},
		onUnload() {
			// 取消回传
			this.returnAdminLngLat("end")
			// 取消车辆坐标定位,定时器
			this.setLocationAddr("end")
			uni.$off('saveSiteNum', (data) => {})
			uni.$off('selectPlan-MapPopup', (data) => {})
			uni.$off('selectSiteNum', (data) => {})
		},
		onHide() {
			// 取消回传
			this.returnAdminLngLat("end")
			// 取消车辆坐标定位,定时器
			this.setLocationAddr("end")
		},
		onShow() {
			uni.showLoading({
				title: "任务加载中..."
			})
			// 实时更新车辆坐标
			this.setLocationAddr("start")
			// 获取任务信息====数据入口
			this.getTaskData().then(resTask => {
				uni.hideLoading()
				console.log("查看配送任务", resTask)
				console.log("查看配送任务ID resTask.map.allShopInfo[0].taskId", resTask.map.allShopInfo[0].taskId)
				// 开始回传当前坐标点
				this.returnAdminLngLat("start")
				// 存储车辆ID  任务ID 
				this.setStorageKey("tobacco_carID", resTask.map.deliveryman[0].carId, "carID")
				// 获取站点列表
				this.getMarkersList(resTask.map.allShopInfo[0].taskId)
				// 获取车辆ID
				// this.getCarId(resTask.map.deliveryman[0].id)
			}).catch(err => {
				console.error(err)
				uni.hideLoading()
			})
		},
		onBackPress(event) {
			if (event.from == 'navigateBack') {
				return false
			}
			uni.showModal({
				title: "警告！",
				content: "退出导航可能导致意外得错误发生！",
				success: (res) => {
					if (res.confirm) {
						uni.reLaunch({
							url: "/pages/distribution/distribution"
						})
						uni.hideLoading()
						return false
					} else {
						return true
					}
				}
			})
			return true
		},
		methods: {
			// 路线规划
			initMapLine(startSite, endSite) {
				// 坐标校验
				if (startSite.longitude == 0 || startSite.latitude == 0 || endSite.longitude == 0 || endSite.latitude ==
					0) {
					uni.hideLoading()
					return uni.showToast({
						title: "站点坐标错误，无法导航",
						icon: "none"
					})
				}

				let origin = startSite.longitude + "," + startSite.latitude
				let destination = endSite.longitude + "," + endSite.latitude
				console.log("本次规划路线坐标参数", startSite, endSite)
				// 更新地图中心点坐标
				this.mapCenterLatitude = startSite.latitude
				this.mapCenterLongitude = startSite.longitude
				// 组织地图markers（起点/终点/车辆点）
				this.markers = []
				this.markers.push({
					id: startSite.id,
					latitude: startSite.latitude,
					longitude: startSite.longitude,
					siteId: startSite.siteId, // 站点ID
					label: startSite.label,
					iconPath: "../../../static/img/map/start.png"
				})
				this.markers.push({
					id: endSite.id,
					latitude: endSite.latitude,
					longitude: endSite.longitude,
					siteId: endSite.siteId, // 站点ID
					label: endSite.label,
					iconPath: "../../../static/img/map/end.png"
				})

				console.log("查看markers地图", this.markers)
				this.initLinePlan() // 初始化地图路线数组数据 polylineComputed & polyline
				// 规划三种行进路线
				for (let LL in this.polylineComputed) {
					let that = this
					// let polyItem = this.polylineComputed[LL]
					myAmapFun.getDrivingRoute({
						origin: origin,
						strategy: that.polylineComputed[LL].strategy,
						destination: destination,
						success: (data) => {
							let points = [];
							let steps = data.paths[0].steps;
							for (var i = 0; i < steps.length; i++) {
								var poLen = steps[i].polyline.split(';');
								for (var j = 0; j < poLen.length; j++) {
									points.push({
										longitude: parseFloat(poLen[j].split(',')[0]),
										latitude: parseFloat(poLen[j].split(',')[1])
									})
								}
							}
							that.polylineComputed[LL].points = [...points] // 存储切割坐标组
							that.polylineComputed[LL].steps = [...steps] // 存储导航提示语
							that.polylineComputed[LL].distance = data.paths[0].distance ? parseInt(data.paths[
								0].distance * 0.001) : 0 // 存储路线距离
							that.polylineComputed[LL].duration = data.paths[0].duration ? parseInt(data.paths[
								0].duration / 60) : 0 // 存储路线时间

							if (LL >= that.polylineComputed.length - 1) {
								setTimeout(() => {
									// 打开规划路线方案抽屉
									uni.$emit("showMapPopup", {
										show: true,
										polyline: [...that.polylineComputed]
									})

									// 默认选择推荐方案（速度最快）
									that.polyline.push(that.polylineComputed[1])
									// 打开道路导航提示
									uni.$emit("showRoad_info", {
										show: true,
										steps: that.polylineComputed[1].steps,
										points: that.polylineComputed[1].points
									})
									uni.hideLoading()
								}, 500)
							}
						},
						fail: function(err) {
							console.error(err)
							uni.hideLoading()
						}
					})
				}
			},

			// 获取站点列表 *******分两种模式****改代码注意两部分同时改，1、直接获取后台数据 2、读取缓存数据
			getMarkersList(taskId) {
				uni.showLoading({
					title: "地图加载..."
				})
				// 校验缓存是否有未执行完的线路任务
				if (!["", -1].includes(this.getStorageKey("tobacco_siteNum", "siteNum"))) {
					console.error("模式2、读取缓存数据")
					let tmpArr = this.getStorageKey("tobacco_markersList", "markers")
					let tmpSiteNum = this.getStorageKey("tobacco_siteNum", "siteNum")

					// let tmpMark = []
					// tmpArr.forEach((item, index) => {
					// 	tmpMark.push({
					// 		id: index,
					// 		// 经纬度数据库中值为反向的，需要注意！！！
					// 		latitude: item.customerShop.lng || 0,
					// 		longitude: item.customerShop.lat || 0,
					// 		siteId: item.id, // 站点ID
					// 		label: {
					// 			content: item.shopname
					// 		},
					// 		flag: 2,
					// 		flagText: "未到达", // 1、已到达 2、未到达
					// 		siteNum: index, // 站点下标
					// 		siteName: item.shopname, // 站点名称
					// 		iconPath: "https://wx.cctobacco.cn/community_img/siteNum.png",
					// 	})
					// })
					// // 存储站点值
					// this.setStorageKey("tobacco_markersList", tmpMark)
					// 初始站点数，默认到达第0站
					// this.setStorageKey("tobacco_siteNum", 0, "siteNum")
					this.initMapLine(tmpArr[tmpSiteNum], tmpArr[tmpSiteNum + 1])
					return
				}

				console.error("模式1、直接获取后台数据")

				uni.request({
					url: requestUrl + '/app/getHome',
					method: 'POST',
					data: {
						taskId: taskId
					},
					success: (res) => {
						if (res.data.code == 200) {
							console.log("站点列表=》》》》》", res)
							let tmpMark = []
							if (res.data.data.taskDetailList.length <= 0) {
								console.error("暂无站点列表", taskId, requestUrl + '/app/getHome', res)
								setTimeout(() => {
									uni.navigateBack({
										delta: 1
									})
								}, 2900)
								return uni.showToast({
									title: "配送任务暂无站点配送列表",
									icon: "none",
									mask: true,
									duration: 3000
								})

							}
							// 重组markers数组=====>>>所有数据源头\所有数据源头\所有数据源头
							res.data.data.taskDetailList.forEach((item, index) => {
								if (item.customerShop && !["", "null", null, 0].includes(item
										.customerShop.lat) && !["", "null", null, 0].includes(item
										.customerShop.lng)) {
									tmpMark.push({
										// 经纬度数据库中值为反向的，需要注意！！！
										latitude: item.customerShop.lng || 0,
										longitude: item.customerShop.lat || 0,
										siteId: item.id, // 站点ID
										label: {
											content: item.shopname
										},
										flag: 2,
										flagText: "未到达", // 1、已到达 2、未到达
										siteName: item.shopname, // 站点名称
										iconPath: "https://wx.cctobacco.cn/community_img/siteNum.png"
									})
								}
							})
							// 联合上面循环处理数据下标，防止选站时使用下标产生下标越界
							for (let idx in tmpMark) {
								tmpMark[idx].id = Number(idx)
								tmpMark[idx].siteNum = Number(idx)
							}
							// 存储站点值
							this.setStorageKey("tobacco_markersList", tmpMark)
							// 初始站点数，默认到达第0站
							this.setStorageKey("tobacco_siteNum", 0, "siteNum")
							console.log("初始化地图，规划路线", tmpMark)
							// 初始化地图，规划路线
							if (tmpMark && tmpMark.length > 1) {
								this.initMapLine(tmpMark[0], tmpMark[1])
							} else {
								console.error(res)
								uni.hideLoading()
							}
						} else {
							console.error(res)
							uni.hideLoading()
						}
					},
					fail: (error) => {
						console.error(error)
						uni.hideLoading()
					}
				})
			},
			// 获取任务信息
			getTaskData() {
				console.log(baseUrl() + '/app/DeliveryTask/deliveryList')
				console.log(JSON.parse(uni.getStorageSync("USERS_KEY")).user.id, {
					data: Encr.encryptData(JSON.stringify({
						userid: JSON.parse(uni.getStorageSync("USERS_KEY")).user.id
					}))
				})
				return new Promise((resolve, reject) => {
					uni.request({
						url: baseUrl() + '/app/DeliveryTask/deliveryList',
						method: 'POST',
						data: Encr.encryptData(JSON.stringify({
							userid: JSON.parse(uni.getStorageSync("USERS_KEY")).user.id
						})),
						success: function(res) {
							if (res.statusCode == '200') {
								let result = JSON.parse(Encr.decrypt(res.data))
								resolve(result)
							} else {
								reject(res)
							}
						},
						fail: (err) => {
							reject(err)
						}
					});
				})
			},
			// 获取车辆ID
			getCarId(taskId) {
				console.log(requestUrl + "/app/getUserId/" + taskId)
				// 特殊接口，需将任务ID直接拼接到url中
				uni.request({
					url: requestUrl + "/app/getUserId/" + taskId,
					// url: "http://106.13.116.185:8089/app/getUserId/07454aef-e4be-45b9-b8f7-872a5c26bdd1",
					method: "GET",
					success: (res) => {
						console.log("获取车辆ID", res.data.data.carid)
						if (res.data.code == 200 && res.data.data.carid) {
							// 存储车辆ID  任务ID 
							this.setStorageKey("tobacco_carID", res.data.data.carid, "carID")
							// 开始回传当前坐标点
							this.returnAdminLngLat("start")
						} else {
							console.error(res)
							uni.showToast({
								title: "车辆信息获取失败",
								icon: "none"
							})
						}
					},
					fail: (err) => {
						console.error(err)
					}
				})
			},
			// 确认到站: 刚刚抵达第X站
			saveSiteNum(num) {
				console.log(num)
				uni.showLoading({
					title: "地图加载..."
				})
				// 赋值当前行驶站点
				this.setStorageKey("tobacco_siteNum", num, "siteNum")
				let tmpArr = this.getStorageKey("tobacco_markersList", "markers")
				// 更改已经到达得站点状态
				for (let i = 0; i < tmpArr.length - 1; i++) {
					// 将过往得站点全部标记为已到达
					if (i < num) {
						tmpArr[i].flag = 1
						tmpArr[i].flagText = "已到达"
						// 更新缓存得站点列表数据
						this.setStorageKey("tobacco_markersList", tmpArr)
					} else {
						break;
					}
				}
				if (tmpArr.length >= num + 1) {
					this.initMapLine(tmpArr[num], tmpArr[num + 1])
					// 提交当前站点得配送状态
					uni.request({
						url: requestUrl + "/app/updateDeliveryStatus",
						method: 'POST',
						data: {
							taskDetailId: tmpArr[num].siteId, // 从上一接口/app/getHome组织到得markers中获取
							deliveryStatus: 12 // deliveryStatus为任务状态 11配送中  12已配送
						},
						success: (res) => {
							console.log(res)
						},
						fail: (err) => {
							console.error(err)
						}
					})
				} else {
					uni.showToast({
						icon: "none",
						title: "所有站点全部配送完成"
					})
				}
			},
			// 自定义选择站点
			selectSiteNum(num, driverMark) {
				console.log(num, driverMark)
				uni.showLoading({
					title: "地图加载..."
				})
				// 赋值当前行驶站点
				this.setStorageKey("tobacco_siteNum", num, "siteNum")
				let tmpSelArr = this.getStorageKey("tobacco_markersList", "markers")
				// 更改已经到达得站点状态
				for (let i = 0; i < tmpSelArr.length - 1; i++) {
					// 将过往得站点全部标记为已到达
					if (i < num) {
						tmpSelArr[i].flag = 1
						tmpSelArr[i].flagText = "已到达"
						// 更新缓存得站点列表数据
						this.setStorageKey("tobacco_markersList", tmpSelArr)
					} else {
						break;
					}
				}
				// 记录当前司机执行了选站操作
				uni.request({
					url: requestUrl + "/app/updateDeliveryStatus",
					method: 'POST',
					data: {
						taskDetailId: tmpSelArr[num].siteId, // 从上一接口/app/getHome组织到得markers中获取
						deliveryStatus: 11 // deliveryStatus为任务状态 11配送中  12已配送
					},
					success: (res) => {
						console.log(res)
					},
					fail: (err) => {
						console.error(err)
					}
				})
				// 规划路线
				this.initMapLine(driverMark, tmpSelArr[num])

			},
			/**
			 * 回传坐标点
			 * @param {Object} type "start"/执行  "end"/停止
			 */
			returnAdminLngLat(type) {
				if (type == "end") {
					return clearInterval(this.lngLatInterval)
				}
				this.lngLatInterval = setInterval(() => {
					let that = this
					uni.getLocation({
						type: 'gcj02',
						"geocode": true,
						success: function(res) {
							uni.request({
								url: requestUrl + '/app/saveLatAndLng',
								method: 'POST',
								data: {
									carId: that.getStorageKey("tobacco_carID", "carID"),
									lngAndLat: res.longitude + "|" + res.latitude
								},
								success: (res) => {
									// console.warn("坐标回传成功", res)
								},
								fail: err => {
									console.error(err)
								}
							})
						},
						fail: (err) => {
							console.error(err)
						}
					});
				}, 30000)
			},
			/**
			 * 设置车辆坐标
			 * @param {Object} type "start"/执行  "end"/停止
			 */
			setLocationAddr(type) {
				if (type == "end") {
					return clearInterval(this.locationSetInterVal)
				}
				this.locationSetInterVal = setInterval(() => {
					// 设定车辆当前位置坐标
					uni.getLocation({
						type: 'gcj02',
						"geocode": true,
						success: res => {
							// 设定车辆当前坐标点
							let isCarLngLat = false
							this.markers.forEach(item => {
								// 寻找车辆marker ID 99999999
								if (item.id && item.id == 99999999) {
									isCarLngLat = true
									// 更新车辆坐标
									item.latitude = res.latitude
									item.longitude = res.longitude
									this.markers.push({})
									this.markers.pop()
								}
							})
							if (this.markers.length <= 0 || !isCarLngLat) {
								// 增加车辆坐标ID
								this.markers.push({
									id: 99999999, // 车辆marker固定ID
									latitude: res.latitude,
									longitude: res.longitude,
									iconPath: "../../../static/img/map/user.png"
								})
							}
						}
					})

				}, 1000)
			},
			/**
			 * 初始化路线规划方案
			 */
			initLinePlan() {
				let result = [{
					title: "距离最短",
					strategy: 2, // 2，距离优先，不考虑路况，仅走距离最短的路线，但是可能存在穿越小路/小区的情况
					duration: 34, // 预计时间（分钟）
					distance: 18, // 距离（公里）
					points: [],
					steps: [],
					color: this.polylineColor,
					width: 10,
					arrowLine: true,
				}, {
					title: "速度最快(推荐方案)",
					strategy: 0, // 0，速度优先，不考虑当时路况，此路线不一定距离最短
					duration: 30, // 预计时间（分钟）
					distance: 20, // 距离（公里）
					points: [],
					steps: [],
					color: this.polylineColor,
					width: 10,
					arrowLine: true,
				}, {
					title: "躲避拥堵",
					strategy: 4, // 4，躲避拥堵，但是可能会存在绕路的情况，耗时可能较长
					duration: 55, // 预计时间（分钟）
					distance: 25, // 距离（公里）
					points: [],
					steps: [],
					color: this.polylineColor,
					width: 10,
					arrowLine: true,
				}]
				this.polylineComputed = [...result]
				this.polyline = []
			},
			/**
			 * 缓存读取
			 * @param {Object} key 缓存key
			 * @param {Object} localKey 本地操作字段名
			 */
			getStorageKey(key, localKey) {
				let result = uni.getStorageSync(key) ? uni.getStorageSync(key) : -1

				if (localKey && result != -1) {
					this[localKey] = result
				}

				return result
			},
			/**
			 * 缓存赋值
			 * @param {Object} key 缓存key
			 * @param {Object} data 缓存数据
			 * @param {Object} localKey 本地操作字段名
			 * markers不更新本地变量，仅更新缓存数据，本地markers只有需要规划路线得两个站点
			 */
			setStorageKey(key, data = "", localKey) {
				if (localKey) {
					this[localKey] = JSON.parse(JSON.stringify(data))
				}
				uni.setStorage({
					key: key,
					data: JSON.parse(JSON.stringify(data))
				})
			},
			// 解析markers数组
			parseMarkers() {
				let markersList_tmp = markersList
				let result = {
					origin: "", // 起点
					waypoints: "", // 途径点
					destination: "", // 终点
				}
				markersList_tmp.forEach((item, index) => {
					if (index == 0) {
						result.origin = item
						// 更新地图中心点坐标
						this.longitude = item.split(",")[0] // 中心点坐标125.324282,43.883938
						this.latitude = item.split(",")[1] // 中心点坐标
					} else if (index == markersList_tmp.length - 1) {
						result.destination = item
					} else {
						result.waypoints = result.waypoints == "" ? item : result.waypoints + ";" + item
					}
				})
				return result
			},
			// 计算当前点是否偏移路线
			/**
			 * @param {Object} lngLat 当前位置坐标 { longitude: longitude, latitude: latitude }
			 * @param {Object} points 路线坐标组 [{ longitude: longitude, latitude: latitude },{ longitude: longitude, latitude: latitude }]
			 * @param {Object} errDistance 误差范围
			 * @return {boolean} true 偏航  false 未偏航
			 */
			offsetMapLine(lngLat, points, errDistance) {
				// console.log(lngLat, points, errDistance)
				// let points = [{
				// 	longitude:"125.330516",
				// 	latitude:"43.822618"
				// },{
				// 	longitude:"125.330273",
				// 	latitude:"43.821551"
				// },{
				// 	longitude:"125.332088",
				// 	latitude:"43.822969"
				// }
				// ]
				// // 当前坐标点
				// let longLat = {
				// 	longitude:"125.332829",
				// 	latitude:"43.822764"
				// }

				let lng = Number(lngLat.longitude)
				let lat = Number(lngLat.latitude)
				let result = false // 是否偏移路线
				for (let i = points.length - 1; i >= 0; i--) {
					// 坐标组中只要存在一个坐标在误差允许范围内，就不算偏移
					let mapDis = this.GetDistance(lng, lat, Number(points[i].longitude), Number(points[i].latitude))
					if (mapDis <= errDistance) {
						// 未偏航
						result = false
						break;
					} else {
						// 已偏航
						result = true
					}
				}
				return result
			},
			/**
			 * 计算两地经纬度坐标距离
			 * @param {Object} lng1 本地坐标经度
			 * @param {Object} lat1 本地坐标维度
			 * @param {Object} lng2 目标地经度
			 * @param {Object} lat2 目标地维度
			 * @return {Number} 单位/米
			 */
			GetDistance(lng1, lat1, lng2, lat2) {
				var radLat1 = lat1 * Math.PI / 180.0;
				var radLat2 = lat2 * Math.PI / 180.0;
				var a = radLat1 - radLat2;
				var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
				var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
					Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
				s = s * 6378.137; // EARTH_RADIUS;
				s = Math.round(s * 10000) / 10000;
				return s * 1000;
			}
		}
	}
</script>

<style>
	map {
		width: 100vw;
		height: 100vh;
		position: relative;
	}
</style>
